<template>
  <div>
    <ele-pro-table
      ref="tableRef"
      row-key="menuKey"
      :columns="columns"
      :datasource="datasource"
      :lazy="true"
      :show-overflow-tooltip="true"
      :load="tableLoad"
      :pagination="{ pageSize: 5, pageSizes: [5, 10, 20] }"
      :export-config="{ fileName: '菜单数据', datasource: exportSource }"
      :print-config="{ datasource: exportSource }"
      @done="handleDone"
    >
      <template #action="{ row }">
        <el-link
          type="primary"
          underline="never"
          @click="reloadChild(row, $event)"
        >
          刷新我的子级
        </el-link>
        <el-divider v-if="row.parent_id" direction="vertical" />
        <el-link
          v-if="row.parent_id"
          type="primary"
          underline="never"
          @click="reloadParent(row)"
        >
          刷新我父级的子级
        </el-link>
      </template>
    </ele-pro-table>
  </div>
</template>

<script setup>
import { ref, nextTick } from "vue";
import { EleMessage, toTree } from "ele-admin-plus/es";
import dayjs from "dayjs";
import { pageMenus, listMenus } from "@/api/system/menu";

/** 表格实例 */
const tableRef = ref(null);

/** 表格列配置 */
const columns = ref([
  {
    type: "index",
    columnKey: "index",
    width: 50,
    align: "center",
  },
  {
    prop: "title",
    label: "菜单名称",
    minWidth: 160,
  },
  {
    prop: "path",
    label: "路由地址",
    minWidth: 180,
  },
  {
    prop: "sort_number",
    label: "排序",
    width: 100,
    align: "center",
  },
  {
    prop: "updateTime",
    label: "更新时间",
    width: 220,
    align: "center",
  },
  {
    width: 280,
    columnKey: "action",
    label: "操作",
    align: "center",
    slot: "action",
    hideInPrint: true,
    hideInExport: true,
  },
]);

/** 表格数据源 */
const datasource = async ({ pages, where, parent }) => {
  const now = Date.now();
  if (parent == null) {
    const res = await pageMenus({ ...where, ...pages, parent_id: 0 });
    return {
      count: res?.count,
      list: res?.list?.map?.((d) => {
        return {
          ...d,
          updateTime: dayjs(now).format("YYYY-MM-DD HH:mm:ss.SSS"),
          menuKey: d.menu_id + "-" + now,
        };
      }),
    };
  }
  const data = await listMenus({ ...where, parent_id: parent.menu_id });
  parent._oldChildrenLength = parent.children?.length || 0;
  return data.map((d) => {
    return {
      ...d,
      updateTime: dayjs(now).format("YYYY-MM-DD HH:mm:ss.SSS"),
      menuKey: d.menu_id + "-" + now,
      _parentTableResolve: parent._tableResolve,
      parent,
    };
  });
};

/** 表格数据加载完成事件 */
const handleDone = ({ response }, parent) => {
  // 解决懒加载下子级无法清空
  if (parent && !response.length && parent._oldChildrenLength) {
    nextTick(() => {
      //console.log(parent);
      parent.hasChildren = false;
      parent.menuKey = parent.menu_id + "-" + Date.now();
    });
  }
};

/** 重写树表格懒加载方法 */
const tableLoad = (row, _treeNode, resolve) => {
  row._tableResolve = resolve;
  tableRef.value?.reload?.(void 0, row, resolve);
};

/** 刷新节点的子级数据 */
const reloadChild = (row, e) => {
  EleMessage.success("已刷新, 可查看控制台发出的请求");
  if (row._tableResolve) {
    tableRef.value?.reload?.(void 0, row, row._tableResolve);
    return;
  }
  const target = e.currentTarget;
  const $tr = target?.parentElement?.parentElement?.parentElement;
  const $icon = $tr?.querySelector?.(".el-table__expand-icon");
  $icon && $icon.click();
};

/** 刷新父级节点的子级数据 */
const reloadParent = (row) => {
  EleMessage.success("已刷新, 可查看控制台发出的请求");
  if (row._parentTableResolve) {
    tableRef.value?.reload?.(void 0, row.parent, row._parentTableResolve);
  }
};

/** 导出和打印全部数据的数据源 */
const exportSource = async ({ where }) => {
  const data = await listMenus({ ...where });
  return toTree({
    data,
    idField: "menu_id",
    parentIdField: "parent_id",
  });
};
</script>
